/**
 * LibManWin.java
 * Main Library Manager Window
 * 
 * @author John Thomason
 *    Date: Feb 16, 2009
 *  Course: CS223
 * Seminar: 6
 *  Assign: Final Exam
 */

//Package
package libman.gui;

//Imported Packages
import javax.swing.*;
import libman.*;
import java.util.logging.*;
import java.util.*;
import java.text.*;
import java.awt.*;

/** Main Library Manager Window */
public class LibManWin
extends JFrame
{
    private LibManModel model = new LibraryManager();
    private String    logName = "Library Manager";
    private Logger     logger = Logger.getLogger(logName);
    
    /** Creates new form LibManWin */
    public LibManWin() {
        initComponents();

        //Add a log handler class
        logger.addHandler(new GuiLogHandler());

        //Default JFrame settings
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jtpBookResults = new javax.swing.JTabbedPane();
        jpnBookMaintenance = new javax.swing.JPanel();
        jpnBookFields = new javax.swing.JPanel();
        jlbId = new javax.swing.JLabel();
        jtfId = new javax.swing.JTextField();
        jlbTitle = new javax.swing.JLabel();
        jtfTitle = new javax.swing.JTextField();
        jlbAuthor = new javax.swing.JLabel();
        jtfAuthor = new javax.swing.JTextField();
        jlbSummary = new javax.swing.JLabel();
        jspnSummary = new javax.swing.JScrollPane();
        jtaSummary = new javax.swing.JTextArea();
        jpnButtons = new javax.swing.JPanel();
        jbnAdd = new javax.swing.JButton();
        jbnFind = new javax.swing.JButton();
        jbnDelete = new javax.swing.JButton();
        jbnListAll = new javax.swing.JButton();
        jbnClear = new javax.swing.JButton();
        jbnQuit = new javax.swing.JButton();
        jpnBookList = new javax.swing.JPanel();
        jspnBookList = new javax.swing.JScrollPane();
        jtaBookList = new javax.swing.JTextArea();
        jpnLogging = new javax.swing.JPanel();
        jspnLogDisplay = new javax.swing.JScrollPane();
        jtaLogDisplay = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Library Manager");

        jpnBookMaintenance.setLayout(new java.awt.BorderLayout());

        jlbId.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jlbId.setText("Book ID");

        jlbTitle.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jlbTitle.setText("Title");

        jlbAuthor.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jlbAuthor.setText("Author");

        jlbSummary.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jlbSummary.setText("Summary");

        jtaSummary.setColumns(20);
        jtaSummary.setRows(5);
        jspnSummary.setViewportView(jtaSummary);

        javax.swing.GroupLayout jpnBookFieldsLayout = new javax.swing.GroupLayout(jpnBookFields);
        jpnBookFields.setLayout(jpnBookFieldsLayout);
        jpnBookFieldsLayout.setHorizontalGroup(
            jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jpnBookFieldsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jspnSummary, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 501, Short.MAX_VALUE)
                    .addGroup(jpnBookFieldsLayout.createSequentialGroup()
                        .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jlbSummary, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jlbAuthor, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jlbTitle, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jlbId, javax.swing.GroupLayout.Alignment.TRAILING))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jtfId, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
                            .addComponent(jtfAuthor, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
                            .addComponent(jtfTitle, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE))))
                .addContainerGap())
        );

        jpnBookFieldsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jlbAuthor, jlbId, jlbSummary, jlbTitle});

        jpnBookFieldsLayout.setVerticalGroup(
            jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnBookFieldsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jlbId)
                    .addComponent(jtfId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jtfTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jlbTitle))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnBookFieldsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jtfAuthor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jlbAuthor))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jlbSummary)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jspnSummary, javax.swing.GroupLayout.DEFAULT_SIZE, 39, Short.MAX_VALUE)
                .addContainerGap())
        );

        jpnBookMaintenance.add(jpnBookFields, java.awt.BorderLayout.CENTER);

        jpnButtons.setLayout(new java.awt.GridLayout(2, 4, 5, 0));

        jbnAdd.setText("Add Book");
        jbnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnAddActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnAdd);

        jbnFind.setText("Find Book");
        jbnFind.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnFindActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnFind);

        jbnDelete.setText("Delete Book");
        jbnDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnDeleteActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnDelete);

        jbnListAll.setText("List All Books");
        jbnListAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnListAllActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnListAll);

        jbnClear.setText("Clear Form");
        jbnClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnClearActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnClear);

        jbnQuit.setText("Quit");
        jbnQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbnQuitActionPerformed(evt);
            }
        });
        jpnButtons.add(jbnQuit);

        jpnBookMaintenance.add(jpnButtons, java.awt.BorderLayout.SOUTH);

        jtpBookResults.addTab("Book Maintenance", jpnBookMaintenance);

        jtaBookList.setColumns(20);
        jtaBookList.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        jtaBookList.setLineWrap(true);
        jtaBookList.setRows(5);
        jtaBookList.setWrapStyleWord(true);
        jspnBookList.setViewportView(jtaBookList);

        javax.swing.GroupLayout jpnBookListLayout = new javax.swing.GroupLayout(jpnBookList);
        jpnBookList.setLayout(jpnBookListLayout);
        jpnBookListLayout.setHorizontalGroup(
            jpnBookListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 525, Short.MAX_VALUE)
            .addGroup(jpnBookListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jpnBookListLayout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jspnBookList, javax.swing.GroupLayout.DEFAULT_SIZE, 501, Short.MAX_VALUE)
                    .addContainerGap()))
        );
        jpnBookListLayout.setVerticalGroup(
            jpnBookListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 243, Short.MAX_VALUE)
            .addGroup(jpnBookListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jpnBookListLayout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jspnBookList, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE)
                    .addContainerGap()))
        );

        jtpBookResults.addTab("Book List", jpnBookList);

        getContentPane().add(jtpBookResults, java.awt.BorderLayout.CENTER);

        jpnLogging.setBorder(javax.swing.BorderFactory.createTitledBorder("Log Display"));

        jtaLogDisplay.setColumns(20);
        jtaLogDisplay.setRows(5);
        jspnLogDisplay.setViewportView(jtaLogDisplay);

        javax.swing.GroupLayout jpnLoggingLayout = new javax.swing.GroupLayout(jpnLogging);
        jpnLogging.setLayout(jpnLoggingLayout);
        jpnLoggingLayout.setHorizontalGroup(
            jpnLoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jspnLogDisplay, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE)
        );
        jpnLoggingLayout.setVerticalGroup(
            jpnLoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jspnLogDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        getContentPane().add(jpnLogging, java.awt.BorderLayout.SOUTH);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * List All Books Button
     * @param evt
     */
    private void jbnListAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnListAllActionPerformed
        jtpBookResults.setSelectedComponent(jpnBookList);
        String sOut = "";
        try {
            for (Book b: model.listBooks()){
                sOut += b.toString() + "\n";
            }//for
            jtaBookList.setText(sOut);
        }
        catch (Exception e){
            logException(e);
        }
    }//GEN-LAST:event_jbnListAllActionPerformed

    /**
     * Find Book Button
     * @param evt
     */
    private void jbnFindActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnFindActionPerformed
        Book book = null;
        try {
            //Handles iterating through text fields
            book = handleFindBookRequest();
            //Display the found book
            if (book != null){
                jtfId.setText(book.getId());
                jtfTitle.setText(book.getTitle());
                jtfAuthor.setText(book.getAuthor());
                jtaSummary.setText(book.getSummary());
            }//if
        }//try
        catch (Exception e){
            logException(e);
        }//catch

    }//GEN-LAST:event_jbnFindActionPerformed

    /**
     * Clear Button
     * @param evt
     */
    private void jbnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnClearActionPerformed
        for (Component c: jpnBookFields.getComponents()){
            if (c instanceof JTextField) ((JTextField)c).setText("");
        }//for
        jtaSummary.setText("");
        jtaLogDisplay.setText("");
    }//GEN-LAST:event_jbnClearActionPerformed

    /**
     * Quit Button
     * @param evt
     */
    private void jbnQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnQuitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jbnQuitActionPerformed

    /**
     * Add Book Button
     * @param evt
     */
    private void jbnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnAddActionPerformed
        try {
            Book book = new Book(jtfId.getText(),
                                 jtfTitle.getText(),
                                 jtfAuthor.getText(),
                                 jtaSummary.getText());
            model.addBook(book);
            jbnClear.doClick();
            jtfId.setText(book.getId());
            jbnFind.doClick();
        }//try
        catch (Exception e){
            logException(e);
        }//catch
    }//GEN-LAST:event_jbnAddActionPerformed

    /**
     * Delete Book Button
     * @param evt
     */
    private void jbnDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbnDeleteActionPerformed
        try {
            model.deleteBook(handleFindBookRequest());
            jbnClear.doClick();
        }//try
        catch (Exception e){
            logException(e);
        }//catch
    }//GEN-LAST:event_jbnDeleteActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jbnAdd;
    private javax.swing.JButton jbnClear;
    private javax.swing.JButton jbnDelete;
    private javax.swing.JButton jbnFind;
    private javax.swing.JButton jbnListAll;
    private javax.swing.JButton jbnQuit;
    private javax.swing.JLabel jlbAuthor;
    private javax.swing.JLabel jlbId;
    private javax.swing.JLabel jlbSummary;
    private javax.swing.JLabel jlbTitle;
    private javax.swing.JPanel jpnBookFields;
    private javax.swing.JPanel jpnBookList;
    private javax.swing.JPanel jpnBookMaintenance;
    private javax.swing.JPanel jpnButtons;
    private javax.swing.JPanel jpnLogging;
    private javax.swing.JScrollPane jspnBookList;
    private javax.swing.JScrollPane jspnLogDisplay;
    private javax.swing.JScrollPane jspnSummary;
    private javax.swing.JTextArea jtaBookList;
    private javax.swing.JTextArea jtaLogDisplay;
    private javax.swing.JTextArea jtaSummary;
    private javax.swing.JTextField jtfAuthor;
    private javax.swing.JTextField jtfId;
    private javax.swing.JTextField jtfTitle;
    private javax.swing.JTabbedPane jtpBookResults;
    // End of variables declaration//GEN-END:variables

    private Book handleFindBookRequest() throws Exception {
        Book book = null;
        for (Component c: jpnBookFields.getComponents()){
            if (c instanceof JTextField){
                if (!((JTextField)c).getText().trim().isEmpty()){
                    book = model.findBook(((JTextField)c).getText().trim());
                    break;
                }
            }//if
        }//for
        return book;
    }//handleFindBookRequest()

    private void logException(Exception e){
        logger.severe(e.toString());
    }//logException

    private class GuiLogHandler
    extends Handler
    {
        //Instance Vars
        private String logMessages;

        DateFormat df = DateFormat.getDateTimeInstance();

        /** Creates a new instance of GuiLogHandler */
        public GuiLogHandler() {
        }

        @Override
        public void flush() {
            throw new UnsupportedOperationException("Not supported yet.");
        }//flush()

        @Override
        public void close() throws SecurityException {
            logMessages = null;
        }//close()

        @Override
        public void publish(LogRecord logRecord) {

            // **  Date String
            Date date = new Date(logRecord.getMillis());
            String dateString = df.format(date);

            // **  Format the log record and publish it using the
            // **  jTextArea1.setText() method
            // **  The formatted output should display the log record:

            // **  Sequence number
            long   seqNumber   = logRecord.getSequenceNumber();
            // **  Log level
            String level       = logRecord.getLevel().getName();
            // **  Log message
            String message     = logRecord.getMessage();
            // **  Source class name
            String className   = logRecord.getSourceClassName();
            // **  Source method name
            String methodName  = logRecord.getSourceMethodName();

            // **  Formatted Message String
            logMessages = String.format("%05d::%s::%s\n" +
                                        "%s::%s\n" +
                                        "%s\n",
                                         seqNumber, dateString, level,
                                         className, methodName,
                                         message);
            // **  Display the formatted log message
            jtaLogDisplay.setText(logMessages);

        }//publish()

    }//GuiLogHandler Class

}//LibManWin
